package me.zhengjie.utils;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.*;

/**
 * 字符串工具类
 */
public class StringUtils {

    private static final Map<Character, Integer> chineseDigitMap = Map.of(
            '一', 1, '二', 2, '三', 3, '四', 4,
            '五', 5, '六', 6, '七', 7, '八', 8, '九', 9
    );

    public static int extractGradeNumber(String gradeStr) {
        if (gradeStr == null || gradeStr.isEmpty()) return -1;

        char ch = gradeStr.charAt(0); // 第一个汉字

        if (gradeStr.startsWith("初")) {
            // 初一 ~ 初三 = 7 ~ 9
            return 6 + chineseDigitMap.getOrDefault(gradeStr.charAt(1), -1);
        } else if (gradeStr.startsWith("高")) {
            // 高一 ~ 高三 = 10 ~ 12
            return 9 + chineseDigitMap.getOrDefault(gradeStr.charAt(1), -1);
        } else if (gradeStr.contains("年级")) {
            // 一年级 ~ 六年级 = 1 ~ 6
            return chineseDigitMap.getOrDefault(ch, -1);
        } else {
            // 兜底：只识别第一个汉字
            return chineseDigitMap.getOrDefault(ch, -1);
        }
    }

    public static Map<String, Object> convertObjectToMap(Object obj) {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.convertValue(obj, new com.fasterxml.jackson.core.type.TypeReference<Map<String, Object>>() {});
    }

    public static List<StrokeData> parseJson(String json) {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // 检查输入JSON是否为空
            if (StrUtil.isBlank(json)) {
                return Collections.emptyList();
            }
            
            // 首先规范化JSON格式，处理特殊字符
            json = json.trim();
            
            // 检查是否以方括号开始和结束
            if (!json.startsWith("[")) {
                json = "[" + json;
            }
            if (!json.endsWith("]")) {
                json = json + "]";
            }
            
            // 替换等号为冒号，同时将键和值加上双引号
            json = json.replaceAll("([a-zA-Z0-9_]+)=([^,{}\\[\\]]+)", "\"$1\":\"$2\"");
            
            // 处理img值中的引号问题
            json = json.replaceAll("\"img\":\"\"([0-9]+)", "\"img\":\"$1");
            
            // 处理值中的引号问题
            json = json.replaceAll("\"([a-zA-Z0-9_]+)\":\"\"([^\"]+)\"\"", "\"$1\":\"$2\"");
            
            // 确保JSON字符串中的大括号和方括号正确闭合
            json = json.replaceAll(",\\s*}", "}"); // 清除结尾的逗号错误
            json = json.replaceAll(",\\s*\\]", "]"); // 清除结尾的逗号错误
            
            try {
                return objectMapper.readValue(json, objectMapper.getTypeFactory().constructCollectionType(List.class, StrokeData.class));
            } catch (JsonProcessingException innerException) {
                // JSON解析失败，尝试手动解析
                System.out.println("标准JSON解析失败，尝试手动解析...");
                return manualParseStrokeData(json);
            }
        } catch (Exception e) {
            // 记录错误的JSON内容
            System.err.println("JSON解析错误，原始内容: " + json);
            System.err.println("错误信息: " + e.getMessage());
            
            // 尝试手动解析作为备选方案
            return manualParseStrokeData(json);
        }
    }

    /**
     * 手动解析笔顺数据，用于处理标准JSON解析失败的情况
     */
    private static List<StrokeData> manualParseStrokeData(String content) {
        List<StrokeData> result = new ArrayList<>();
        try {
            // 去除方括号
            if (content.startsWith("[")) {
                content = content.substring(1);
            }
            if (content.endsWith("]")) {
                content = content.substring(0, content.length() - 1);
            }
            
            // 按大括号分割各个对象
            String[] objects = content.split("\\{");
            
            for (String obj : objects) {
                if (obj.trim().isEmpty()) {
                    continue;
                }
                
                // 清理结尾的大括号和逗号
                obj = obj.replaceAll("\\}\\s*,?\\s*$", "");
                
                // 解析各个属性
                String img = extractValue(obj, "img");
                String value = extractValue(obj, "value");
                String simple = extractValue(obj, "simple");
                String pic = extractValue(obj, "pic");
                
                // 只有当pic属性存在时才添加到结果中
                if (pic != null && !pic.isEmpty()) {
                    result.add(new StrokeData(img, value, simple, pic));
                }
            }
        } catch (Exception e) {
            System.err.println("手动解析笔顺数据失败: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 从字符串中提取指定键的值
     */
    private static String extractValue(String content, String key) {
        // 查找键的位置
        int keyIndex = content.indexOf(key + "=");
        if (keyIndex == -1) {
            return "";
        }
        
        // 获取值开始的位置
        int valueStart = keyIndex + key.length() + 1;
        
        // 查找值结束的位置（下一个逗号或字符串结束）
        int valueEnd = content.indexOf(",", valueStart);
        if (valueEnd == -1) {
            valueEnd = content.length();
        }
        
        // 提取值并去除两端空白
        return content.substring(valueStart, valueEnd).trim();
    }

    /**
     * 生成SVG内容，确保包含所有必要的XML命名空间和属性
     * @param strokeDataList 笔顺数据列表
     * @param strokeNumber 指定的笔画序号，该笔画及之前的笔画会变成黑色，为null或超出范围时所有笔画默认为灰色
     * @return 生成的SVG内容
     */
    public static String generateSvg(List<StrokeData> strokeDataList, Integer strokeNumber) {
        if (strokeDataList == null || strokeDataList.isEmpty()) {
            return "";
        }
        
        StringBuilder svgContent = new StringBuilder();
        svgContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n")
                .append("<svg xmlns=\"http://www.w3.org/2000/svg\" ")
                .append("xmlns:xlink=\"http://www.w3.org/1999/xlink\" ")
                .append("version=\"1.1\" ")
                .append("width=\"66\" height=\"49\" ")
                .append("viewBox=\"0 0 66 49\" ")
                .append("style=\"width: 66px; height: 49px;\">\n")
                .append("  <g transform=\"translate(1, 45) scale(0.05, -0.0456)\">\n");

        // 如果strokeNumber为null，设置为0，表示所有笔画都使用默认颜色
        int currentStrokeNumber = strokeNumber != null ? strokeNumber : 0;
        
        for (int i = 0; i < strokeDataList.size(); i++) {
            StrokeData data = strokeDataList.get(i);
            if (data.pic != null && !data.pic.isEmpty()) {
                String strokeColor = i < currentStrokeNumber ? "rgb(0, 0, 0)" : "rgb(184, 184, 184)";
                svgContent.append("    <path d=\"")
                        .append(data.getPic())
                        .append("\" style=\"fill: ")
                        .append(strokeColor)
                        .append(";\"/>\n");
            }
        }

        svgContent.append("  </g>\n")
                .append("</svg>");
        
        return svgContent.toString();
    }

    /**
     * 生成SVG内容 - 不指定笔画序号的版本，默认所有笔画为灰色
     * @param strokeDataList 笔顺数据列表
     * @return 生成的SVG内容
     */
    public static String generateSvg(List<StrokeData> strokeDataList) {
        return generateSvg(strokeDataList, null);
    }

    public static class StrokeData {
        public String img;
        public String value;
        public String simple;
        public String pic;
        
        // 添加无参构造器
        public StrokeData() {}
        
        // 添加参数构造器，方便创建对象
        public StrokeData(String img, String value, String simple, String pic) {
            this.img = img;
            this.value = value;
            this.simple = simple;
            this.pic = pic;
        }

        // 添加 getter 和 setter
        public String getImg() {
            return img != null ? img : "";
        }

        public void setImg(String img) {
            this.img = img;
        }

        public String getValue() {
            return value != null ? value : "";
        }

        public void setValue(String value) {
            this.value = value;
        }

        public String getSimple() {
            return simple != null ? simple : "";
        }

        public void setSimple(String simple) {
            this.simple = simple;
        }

        public String getPic() {
            return pic != null ? pic : "";
        }

        public void setPic(String pic) {
            this.pic = pic;
        }

        // 验证对象是否有效
        public boolean isValid() {
            return pic != null && !pic.isEmpty();
        }

        // 可以根据需要添加 toString 方法，方便调试
        @Override
        public String toString() {
            return "StrokeData{" +
                    "img='" + getImg() + '\'' +
                    ", value='" + getValue() + '\'' +
                    ", simple='" + getSimple() + '\'' +
                    ", pic='" + getPic() + '\'' +
                    '}';
        }
    }
} 